package com.moonshineproject.plugin.actionscript.as3parser
{
	import com.moonshineproject.plugin.actionscript.as3parser.parsers.AS3ParserUtil;
	import com.moonshineproject.plugin.actionscript.as3parser.parsers.DefinitionParser;
	import com.moonshineproject.plugin.actionscript.as3parser.parsers.ExtensionParser;
	import com.moonshineproject.plugin.actionscript.as3parser.parsers.ImportParser;
	import com.moonshineproject.plugin.actionscript.as3parser.vo.ClassVO;
	import com.moonshineproject.plugin.actionscript.as3parser.vo.PackageVO;
	
	import flash.filesystem.File;
	
	import org.as3commons.asblocks.parser.api.IParserNode;
	import org.as3commons.asblocks.parser.errors.UnExpectedTokenError;
	import org.as3commons.asblocks.parser.impl.AS3Parser;
	import org.as3commons.mxmlblocks.parser.impl.MXMLParser;
	
	public class SourceFileParser
	{
		protected var metadata:MetadataManager;
		protected var sourceDirectories:Vector.<File>;
		
		public function SourceFileParser(metadata:MetadataManager, sourceDirectories:Vector.<File>)
		{
			this.metadata = metadata;
			this.sourceDirectories = sourceDirectories;
		}
		
		public function parseDir(dir:File, root:File, removeOldEntries:Boolean=true):void
		{
			var listing:Array = dir.getDirectoryListing();
			for each (var file:File in listing)
			{
				if (!file.isDirectory)
				{
					parseFile(file, removeOldEntries);
				}
				else
				{
					parseDir(file, root, removeOldEntries);
				}
			}	
		}

		public function parseFile(file:File, removeOldEntry:Boolean=true):void
		{
			if (file.extension == "as")
			{
				// Parse file
				var as3Parser:AS3Parser = new AS3Parser();
				as3Parser.parseBlocks = false;
				try {
					as3Parser.buildFileAst(file.nativePath);
				}
				catch (e:UnExpectedTokenError)
				{
					trace("Failed to parse " + file.nativePath)
					trace(e.message);
					return;
				}
				
				// Find imports
				var as3Imp:ImportParser = new ImportParser(as3Parser.result, metadata, sourceDirectories);
				as3Imp.resolveImports();
				
				// Resolve definitions
				var as3Def:DefinitionParser = new DefinitionParser(as3Parser.result, as3Imp);
				as3Def.resolveTopDefinitions();
				
				// Find base class
				var as3Ext:ExtensionParser = new ExtensionParser(as3Parser.result, as3Imp);
				as3Ext.resolveExtend();
				
				if (as3Def.className == null)
				{
					trace("WARNING: Could find name for class. Skipping " + file.nativePath);
					return;
				}
				
				var as3Class:ClassVO = new ClassVO();
				as3Class.name = as3Def.className;
				as3Class.members = as3Def.definitions;
				as3Class.extendsClass = as3Ext.extendsClass;
				
				//trace("added class " + as3Class.name);
				
				var pkg:PackageVO = AS3ParserUtil.findOrCreatePackage(as3Imp.packageName, metadata.globalPackageCache);
				if (removeOldEntry)
				{
					var classToRemove:ClassVO = pkg.getClass(as3Class.name);
					if (classToRemove)
					{
						pkg.classes.splice(pkg.classes.indexOf(classToRemove), 1);
					}
				}
				
				pkg.addClass(as3Class);
			}
			else if (file.extension == "mxml")
			{
				var mxmlParser:MXMLParser = new MXMLParser();
				var ast:IParserNode = mxmlParser.buildFileAst(file.nativePath);
				
				// TODO: Everything :)
			}
		}

		
	}
}